package com.ruoyi.lxy.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.lxy.domain.TProject;
import com.ruoyi.lxy.domain.TRoute;
import com.ruoyi.lxy.domain.TSelectUser;
import com.ruoyi.lxy.domain.bo.TRouteBo;
import com.ruoyi.lxy.domain.vo.TProjectVo;
import com.ruoyi.lxy.domain.vo.TSelectUserVo;
import com.ruoyi.lxy.mapper.TProjectMapper;
import com.ruoyi.lxy.mapper.TRouteMapper;
import com.ruoyi.lxy.mapper.TSelectUserMapper;
import com.ruoyi.lxy.service.ITProjectService;
import com.ruoyi.lxy.service.ITSelectUserService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.ruoyi.lxy.domain.bo.TTimeBo;
import com.ruoyi.lxy.domain.vo.TTimeVo;
import com.ruoyi.lxy.domain.TTime;
import com.ruoyi.lxy.mapper.TTimeMapper;
import com.ruoyi.lxy.service.ITTimeService;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Collection;
import java.util.stream.Collectors;

/**
 * 时间段Service业务层处理
 *
 * @author ruoyi
 * @date 2023-08-24
 */
@RequiredArgsConstructor
@Service
public class TTimeServiceImpl implements ITTimeService {

    private final TTimeMapper baseMapper;
    private final TRouteMapper routeMapper;
    private final TProjectMapper projectMapper;
    private final ITSelectUserService itSelectUserService;
    private final TSelectUserMapper tSelectUserMapper;

    /**
     * 查询时间段
     */
    @Override
    public TTimeVo queryById(Long id) {
        TTimeVo tTimeVo = baseMapper.selectVoById(id);
        tTimeVo.setRoute(routeMapper.selectVoById(tTimeVo.getRouteId()).getName());
        return tTimeVo;
    }

    /**
     * 查询时间段列表
     */
    @Override
    public TableDataInfo<TTimeVo> queryPageList(TTimeBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<TTime> lqw = buildQueryWrapper(bo);
        switch (LoginHelper.getLoginUser().getRoles().get(0).getRoleName()) {
            case "旅行社": {
                Long agencyId=LoginHelper.getLoginUser().getUserId();
                //选择的路线限定
                if (bo.getRouteIds() != null && !bo.getRouteIds().isEmpty()) {
                    break;
                    //筛选，默认请求的routeId都是属于该旅行社和项目的
//                    lqw.in(TTime::getRouteId, bo.getRouteIds());
                } else {
                    List<Long> projectIds=projectMapper.selectAvailableProjectListByAgencyId(agencyId);
                    if(projectIds==null && projectIds.size()!=1) return null;
                    //查看属于有效项目且属于该旅行社的路线
                    List<Long> routeIds = routeMapper.selectForAgency(LoginHelper.getLoginUser().getUserId(),projectIds.get(0));
                    if(routeIds==null || routeIds.size()==0) return null;
                    //查看当前旅行社可查看的项目（旅行社拥有的项目、正在进行中的项目
                    lqw.in(!routeIds.isEmpty(), TTime::getRouteId, routeIds);
                }
                //旅行社只能查看已成行路线
                lqw.eq(TTime::getCanGo, 1);//1默认成团
            }
        }
        Page<TTimeVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询时间段列表
     */
    @Override
    public List<TTimeVo> queryList(TTimeBo bo) {
        LambdaQueryWrapper<TTime> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<TTime> buildQueryWrapper(TTimeBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<TTime> lqw = Wrappers.lambdaQuery();
        if(bo.getRouteIds()!=null && bo.getRouteIds().size()!=0){
            lqw.in(TTime::getRouteId, bo.getRouteIds());
        }

        lqw.eq(bo.getRouteId() != null, TTime::getRouteId, bo.getRouteId());
        lqw.ge(bo.getStartTime() != null, TTime::getStartTime, bo.getStartTime());
        lqw.le(bo.getEndTime() != null, TTime::getEndTime, bo.getEndTime());
        lqw.eq(bo.getMax() != null, TTime::getMax, bo.getMax());
        lqw.eq(bo.getCount() != null, TTime::getCount, bo.getCount());
        lqw.eq(bo.getStaffMax() != null, TTime::getStaffMax, bo.getStaffMax());
        lqw.eq(bo.getStaffCount() != null, TTime::getStaffCount, bo.getStaffCount());
        lqw.eq(bo.getCanGo() != null, TTime::getCanGo, bo.getCanGo());
        lqw.eq(bo.getStatus() != null, TTime::getStatus, bo.getStatus());
        //模糊查询出路线id
        List<Long> IDs = routeMapper.selectByName(bo.getRoute());
        if (!IDs.isEmpty())
            lqw.in(bo.getRoute() != null, TTime::getRouteId, IDs);
        else
            //解决查询时ids为空，会查全部数据
            lqw.eq(bo.getRoute() != null, TTime::getRouteId, bo.getRoute());
        return lqw;
    }

    /**
     * 新增时间段
     */
    @Override
    public Boolean insertByBo(TTimeBo bo) {
        bo.setCount(0L);
        bo.setStaffCount(0L);
        TTime add = BeanUtil.toBean(bo, TTime.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改时间段
     */
    @Override
    public Boolean updateByBo(TTimeBo bo) {
        TTime update = BeanUtil.toBean(bo, TTime.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(TTime entity) {
        //如果路线不是已通过状态，不能添加时间段
        if (routeMapper.selectById(entity.getRouteId()).getStatusCode() != 3) {
            throw new IllegalArgumentException("当前路线未通过审核，不能添加或修改时间段，请将其审核通过后进行操作");
        }
    }

    /**
     * 批量删除时间段
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    /**
     * 设置成行路线
     */
    @Override
    public Boolean setCanGoByIds(Collection<Long> ids) {
        LambdaUpdateWrapper<TTime> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.in(TTime::getId, ids).set(TTime::getCanGo, 1);
        return baseMapper.update(null, lambdaUpdateWrapper) > 0;
    }

    /**
     * 设置路线未成形
     */
    @Override
    public Boolean setNotCanGoByIds(Collection<Long> ids) {
        LambdaUpdateWrapper<TTime> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.in(TTime::getId, ids).set(TTime::getCanGo, 0);
        return baseMapper.update(null, lambdaUpdateWrapper) > 0;
    }

    /**
     * 补报方法
     */
    @Override
    public Boolean ReselectTime(String reselectStart, String reselectEnd, Collection<Long> ids) {
        //日期转换
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            Date startTime = dateFormat.parse(reselectStart);
            Date endTime = dateFormat.parse(reselectEnd);
            //System.out.println("开始时间：" + startTime + " 结束时间：" + endTime + " 时间段：" + ids);
            //开始补报的逻辑
            LambdaUpdateWrapper<TTime> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            //修改日期
            lambdaUpdateWrapper.in(TTime::getId, ids)
                .set(TTime::getStartTime, startTime)
                .set(TTime::getEndTime, endTime)
                .set(TTime::getStatus,1);
            //项目补报时间添加
            // 根据时间id查询路线id
            Long routeId = baseMapper.selectById(ids.toArray(new Long[ids.size()])[0]).getRouteId();
            // 根据路线id查询到项目id
            Long projectId = routeMapper.selectById(routeId).getProjectId();
            //根据项目id查询到项目，修改项目补报时间
            TProject project = projectMapper.selectById(projectId);
            project.setReselectStart(startTime);
            project.setReselectEnd(endTime);
            projectMapper.updateById(project);

            return baseMapper.update(null, lambdaUpdateWrapper) > 0;
        } catch (ParseException e) {
            e.printStackTrace();
            return false;
        }
    }


    /**
     * 路线删除时校验是否有对应时间段
     */
    @Override
    public Boolean CheckTimeExist(Long routeId) {
        return baseMapper.exists(new LambdaQueryWrapper<TTime>().eq(TTime::getRouteId, routeId));
    }

    /**
     * 查询未成行路线列表
     */
    @Override
    public TableDataInfo<TTimeVo> queryPageNotCanGoList(Long projectId, TTimeBo bo, PageQuery pageQuery) {
        //首先根据projectId查询到项目对应的所有路线
        TRouteBo tRouteBo = new TRouteBo();
        tRouteBo.setProjectId(projectId);
        LambdaQueryWrapper<TRoute> lqw1 = new LambdaQueryWrapper<>();
        lqw1.eq(TRoute::getProjectId, projectId);
        List<Long> routes = routeMapper.selectByProjectId(projectId);

        LambdaQueryWrapper<TTime> lqw = buildQueryWrapper(bo);
        //如果routes为空，说明该项目没有路线，直接返回空
        if (routes.isEmpty()) {
            Page<TTimeVo> result = new Page<>();
            return TableDataInfo.build(result);
        }
        lqw.in(TTime::getRouteId, routes);

        lqw.eq(TTime::getCanGo, 0);
        Page<TTimeVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        for (TTimeVo tTimeVo : result.getRecords()) {
            tTimeVo.setRoute(routeMapper.selectVoById(tTimeVo.getRouteId()).getName());
        }
        return TableDataInfo.build(result);
    }

    /**
     * 查询成行路线列表
     */
    @Override
    public TableDataInfo<TTimeVo> queryPageCanGoList(Long projectId, TTimeBo bo, PageQuery pageQuery) {
        //首先根据projectId查询到项目对应的所有路线
        TRouteBo tRouteBo = new TRouteBo();
        tRouteBo.setProjectId(projectId);
        LambdaQueryWrapper<TRoute> lqw1 = new LambdaQueryWrapper<>();
        lqw1.eq(TRoute::getProjectId, projectId);
        List<Long> routes = routeMapper.selectByProjectId(projectId);

        LambdaQueryWrapper<TTime> lqw = buildQueryWrapper(bo);
        //如果routes为空，说明该项目没有路线，直接返回空
        if (routes.isEmpty()) {
            Page<TTimeVo> result = new Page<>();
            return TableDataInfo.build(result);
        }
        lqw.in(TTime::getRouteId, routes);

        lqw.eq(TTime::getCanGo, 1);
        Page<TTimeVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        for (TTimeVo tTimeVo : result.getRecords()) {
            tTimeVo.setRoute(routeMapper.selectVoById(tTimeVo.getRouteId()).getName());
        }
        return TableDataInfo.build(result);
    }

    /**
     * 清空所有未成形时间段报名人员，不删除未成形时间段
     */
    @Override
    public Boolean removeNotcango(Long projectId) {
        //首先根据projectId查询到项目对应的所有未成形时间段
        List<Long> routesId = routeMapper.selectByProjectId(projectId);
        LambdaQueryWrapper<TTime> lqw = new LambdaQueryWrapper<>();
        lqw.in(TTime::getRouteId, routesId)
            .eq(TTime::getCanGo, 0);

        List<Long> notcangoIds = baseMapper.selectVoList(lqw).stream()
            .map(TTimeVo::getId).collect(Collectors.toList());
        for (Long notcangoId : notcangoIds) {
            //根据时间段id，查询到所有报名人员
            Collection<Long> userIds = tSelectUserMapper.selectVoList(
                    new LambdaQueryWrapper<TSelectUser>().eq(TSelectUser::getTimeId, notcangoId)).stream()
                .map(TSelectUserVo::getUserId).collect(Collectors.toList());
            for (Long userId : userIds) {
                boolean timeSelectFlag = itSelectUserService.deleteWithValidById(userId, notcangoId, true);
                if (!timeSelectFlag) {
                    return false;
                }
            }
        }
        //功能完成
        return true;
    }
}
